package cn.jsu.oj.dispatchServer.satellite.netty.dispatcher;

import cn.jsu.oj.dispatchServer.satellite.factory.Factory;
import cn.jsu.oj.dispatchServer.satellite.handler.Handler;
import cn.jsu.oj.dispatchServer.satellite.pojo.net.AbsPackNet;
import cn.jsu.oj.dispatchServer.satellite.pojo.net.PackNet;
import cn.jsu.oj.dispatchServer.satellite.util.NetUtil;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import java.io.FileNotFoundException;
import java.util.concurrent.ExecutorService;

/**
 * 包分发器
 *
 * @author shan
 * @date 2022/06/30
 */
@Slf4j
@Component("packDispatcher")
@DependsOn("handlerFactory")
public class PackDispatcher implements Dispatcher {

    /**
     * 执行线程池
     */
    @Autowired
    ExecutorService executorService;

    /**
     * 处理器工厂
     */
    @Autowired
    Factory handlerFactory;

    /**
     * 消息分发
     *
     * @param channel 通道
     * @param msg     消息
     */
    @Override
    public void dispatch(Channel channel, Object msg) {
//        log.info("----------开始分发......");
        String identity = NetUtil.getIdentify(channel);
        AbsPackNet absPackNet = (AbsPackNet) msg;
        Short typeNo = absPackNet.getTypeNo();
        PackNet<?> packNet = new PackNet<>(identity, channel, absPackNet);
        switchHandler(packNet, typeNo);
    }

    /**
     * 选择消息处理器
     *
     * @param packNet net包
     * @param typeNo  类型编号
     */
    private void switchHandler(PackNet<?> packNet, Short typeNo) {
        try {
            ((Handler) handlerFactory.getProduct(typeNo))
                    .handle(packNet);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
